home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 3
/
Cream of the Crop 3.iso
/
comm
/
wnos5src.zip
/
NNTPCLI.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-10-03
|
22KB
|
1,028 lines
/*
*
* NNTP Client - See RFC977
* Jeffrey R. Comstock. - NR0D - Bloomington, Minnesota USA
* Copyright 1990 Jeffrey R. Comstock, All Rights Reserved.
* Permission granted for non-commercial copying and use, provided
* this notice is retained.
*
* DB3FL 9107xx: heavily rewritten and bug fixing in file-handling
* DB3FL 920121: splitted into several files
* DB3FL 920131: included IHAVE command/offer to server
* DG1ZX 9210xx: minimizing overhead in ihave cmd and bug fixing
*
*/
#include <stdio.h>
#include <dos.h>
#include <time.h>
#include <ctype.h>
#include <dir.h>
#include <io.h>
#include "global.h"
#include "config.h"
#include "nntp.h"
#include "files.h"
#include "domain.h"
#include "socket.h"
#include "cmdparse.h"
#include "session.h"
#include "netuser.h"
#ifdef LZW
#include "lzw.h"
#endif
#include "clients.h"
static char quitcmd[] = "QUIT\n";
struct post Post;
static int16 NnIhave = 0;
#undef NNTP_LT /* not yet used */
#ifdef NNTP_LT
static int Nntp_lifetime = 30; /* 30 days of lifetime per default */
#endif
/* handles the response code of an incoming msg
* returncode: -1 error; 0 no code; value of response code on success */
static int near
getreply(struct nntpserv *cb)
{
int response;
char *cp;
while(recvline(cb->s,cb->buf,LineLen) != -1) {
/* skip informative messages and blank lines */
if(*cb->buf == '\0' || *cb->buf == '1') {
continue;
}
if((cp = strchr(cb->buf,' ')) != NULLCHAR) {
*cp = '\0';
response = atoi(cb->buf);
*cp = ' ';
} else {
return -1;
}
return response;
}
return -1;
}
/*
* checks id from IHAVE offer against existing articles id received by
* newnews command. When this test passed, checks if one of the hostname
* in pathfield is identical with hostname, we are polling now. (DG1ZX)
*
* return-code: 0 = no such article ==> IHAVE ok
* 1 = article already exists ==> don't offer
*
*/
static int near
check_ihave(FILE *fp,char *id,struct nntpserv *mp,char *hostn)
{
char *p = strchr(id,'<');
/* checks if article is offered in this session from host */
rewind(fp);
for (;;) {
if(fgets(mp->buf,LineLen,fp) == NULL) {
break;
}
if(strstr(mp->buf,p) != NULL) {
return 1;
}
}
if(hostn == NULLCHAR) {
return 0;
}
/* now we check the pathfield of this article */
strcpy(mp->buf,id);
xfree(id);
p = strchr(mp->buf,'>') + 1;
*p = '\0'; /* cut off CR LF ! */
return (doarticle(mp,0,hostn) ? 0 : 1);
}
static char * near
pollpos(char *dest,FILE *f)
{
int32 t;
char *cp, line[LineLen];
rewind(f);
for(t = 0L; fgets(line,LineLen,f) != NULL; t = ftell(f)) {
if((cp = strchr(line,' ')) == NULLCHAR) {
/* something wrong with this line, skip it */
continue;
}
*cp = '\0';
if(strcmp(line,dest) == 0) {
fseek(f,t,SEEK_SET);
return cp + 1;
}
}
return 0;
}
static void
nntppoll(int unused,void *cb1,void *p)
{
char *cp;
struct sockaddr_in fsocket;
struct nntpserv *cb;
FILE *f = NULLFILE, *f1 = NULLFILE, *pf = NULLFILE;
int err = 0, r, ret;
int32 SavePollTime;
struct tm *ltm;
struct Server *np = (struct Server *)cb1;
if (!Filecheck)
if(check_system())
return;
if(availmem() == 0 || (pf = Fopen(Poll,"r+",0,1)) == NULLFILE)
return;
np->busy = TRUE;
cb = mxallocw(sizeof(struct nntpserv));
cb->buf = mxallocw(LINELEN);
SavePollTime = currtime;
/* if no entry for host in poll-file exist, set date to yesterday (DG1ZX) */
if((cp = pollpos(np->name,pf)) == NULLCHAR) {
int32 lastday = SavePollTime - DAYS;
ltm = gmtime(&lastday);
sprintf(cb->newnews,"%02d%02d%02d %02d%02d%02d",
ltm->tm_year,ltm->tm_mon + 1,ltm->tm_mday,
ltm->tm_hour,ltm->tm_min,ltm->tm_sec);
} else {
cb->newnews = strxdup(cp);
}
rip(cb->newnews);
Fclose(pf);
fsocket.sin_family = AF_INET;
fsocket.sin_addr.s_addr = np->address;
fsocket.sin_port = IPPORT_NNTP;
if((cb->s = socket(AF_INET,SOCK_STREAM,0)) == -1) {
goto quit;
}
sockmode(cb->s,SOCK_ASCII);
if(connect(cb->s,(char *)&fsocket,SOCKSIZE) == -1) {
goto quit;
}
log(cb->s,9983,"NNTP Poll");
if(getreply(cb) == -1) { /* throw away any hello msg */
goto quit;
}
#ifdef LZW
if(LzwActive) {
usprintf(cb->s,"XLZW %d %d\n",Lzwbits,Lzwmode);
if((ret = getreply(cb)) == 235) { /* eat negative response */
lzwinit(cb->s,Lzwbits,Lzwmode);
}
}
#endif
usputs(cb->s,"SLAVE\n");
if(getreply(cb) != 202) {
goto quit;
}
if((f = Tmpfile(0,1)) == NULLFILE) {
goto quit;
}
cb->states = N_SLAVE;
usprintf(cb->s,"NEWNEWS %s %s\n",np->arg1,cb->newnews);
if(getreply(cb) != 230) {
goto quit1;
}
if(recv_file(f,cb->s) == -1) {
goto quit1;
}
if((f1 = Tmpfile(cb->s,1)) == NULLFILE) {
goto quit1;
}
rewind(f);
while(fgets(cb->buf,LineLen,f) != NULL) {
rip(cb->buf);
if(strcmp(cb->buf,".") == 0) {
break;
}
if(check_article(cb->buf) == 1) {
continue;
}
usprintf(cb->s,"ARTICLE %s\n",cb->buf);
for (;;) {
if((r = recvline(cb->s,cb->buf,LineLen)) == -1) {
break;
}
rip(cb->buf);
if(!isdigit(cb->buf[0])) {
r = -1;
continue;
} else {
r = atoi(cb->buf);
break;
}
}
if(r == -1) {
Fclose(f1);
goto quit1;
}
if(r == 220) {
if(recv_file(f1,cb->s) == -1) {
Fclose(f1);
goto quit1;
}
rewind(f1);
while(fgets(cb->buf,LineLen,f1) != NULL) {
rip(cb->buf);
if (strnicmp(cb->buf,Hdrs[MSGID],12) == 0) {
cp = strchr(cb->buf,' ');
cb->id = strxdup((*++cp < 32) ? "(none)" : cp);
break;
}
}
/* minimum header in article required !
* Now check again, if same news exists in history (DG1ZX) */
if (garbled(f1) == 0 && check_article(cb->id) == 0) {
rewind(f1);
xfer_article2(f1,cb);
}
}
Fclose(f1);
if ((f1 = Tmpfile(cb->s,1)) == NULLFILE) {
goto quit1;
}
}
Fclose(f1);
/* IHAVE offer */
if(NnIhave && (f1 = Tmpfile(0,0)) != NULLFILE) {
sprintf(cb->buf,"%s %s",NnIhave == 2 ? "*" : np->arg1,cb->newnews);
if(newnews(cb,f1) == 1) {
rewind(f1);
while(fgets(cb->buf,LINELEN,f1) != NULL) {
/* minimize overhead (DG1ZX) */
char *cp = strxdup(cb->buf);
if(check_ihave(f,cp,cb,np->name)) {
continue;
}
usprintf(cb->s,"IHAVE %s",cb->buf);
if((ret = getreply(cb)) == -1) {
err = 1;
break;
}
if(ret != 335) {
continue;
}
rip(cb->buf);
if(doarticle(cb,0,NULLCHAR) < 1) {
usputs(cb->s,NEol);
if((ret = getreply(cb)) == -1) {
err = 1;
break;
}
continue;
}
if((ret = getreply(cb)) != 235) {
continue;
}
}
}
Fclose(f1);
}
/*
* update pollfile
*/
if(!err && (pf = Fopen(Poll,"r+",0,0)) != NULLFILE) {
struct tm *ltm;
pollpos(np->name,pf);
ltm = gmtime(&SavePollTime);
/* now write back the name of the server, date and time */
fprintf(pf,"%s %02d%02d%02d %02d%02d%02d\n",
np->name,
ltm->tm_year,ltm->tm_mon + 1,ltm->tm_mday,
ltm->tm_hour,ltm->tm_min,ltm->tm_sec);
Fclose(pf);
}
quit1:
Fclose(f);
quit:
usputs(cb->s,quitcmd);
if(getreply(cb) == -1) ;
xfree(cb->newnews);
if((cp = sockerr(cb->s)) == NULLCHAR) {
cp = "EOF";
}
log(cb->s,9983,"NNTP closed %s",cp);
close_s(cb->s);
xfree(cb->buf);
xfree(cb);
np->busy = FALSE;
}
static char * near
input_line(char *msg,struct session *sp)
{
static char buf[LineLen];
for (;;) {
usputs(sp->output,msg);
usflush(sp->output);
if(recvline(sp->input,buf,LineLen) == -1) {
return NULLCHAR;
}
rip(buf);
if(!check_blank(buf)){
return buf;
}
}
}
/* ---------------------- NNTP Client subcmds ----------------------- */
/* lists active newsgroups
* returncode: -1 if error; 0 success */
static int
donnactive(int argc,char **argv,void *p)
{
FILE *fp;
char line[LINELEN], *cp;
if((fp = Fopen(Active,READ_TEXT,0,1)) != NULLFILE) {
tputs("Msg# next post newsgroups\n");
while(fgets(line,LINELEN,fp) != NULL) {
if((cp = strchr(line,' ')) != NULLCHAR) {
*cp = '\0';
rip(++cp);
tprintf("%s %s\n",cp,line);
}
}
Fclose(fp);
return 0;
}
return -1;
}
/* add nntp servers to list */
static int
donnadds(int argc,char **argv,void *p)
{
struct Server *np;
int i;
if((np = addserver(IPPORT_NNTP,argv[1])) == NULLSERVER)
return -1;
np->arg1 = mxallocw(LineLen);
for (i = 2; i < argc; i++) {
if((strlen(np->arg1) + strlen(argv[i]) + 2) >= LineLen) {
tprintf("To many groups, '%s' ignored\n", argv[i]);
} else {
/* it's a group, and it fits... add it to list */
if (*np->arg1 != '\0')
strcat(np->arg1, ",");
strcat(np->arg1,argv[i]);
}
}
return 0;
}
#ifdef NNTPENH
/*
This command will control, how incoming articles are processed.
If fullauto flag is set, the nntp control files are updated to include
the new group and the subdirectories are automaticly generated.
Otherwise, all news that are not in the active file will go to
\spool\news\junk (DG1ZX).
Syntax: nntp config <yes|no>
Default: nntp config yes
*/
static int
donnconfig(int argc,char **argv,void *p)
{
return setbool(&fullauto,"NNTP AutoConfig",argc,argv);
}
#endif
#ifdef NNTPENH
/*
This command will add a new newsgroup to the filesystem. (DG1ZX)
Syntax: nntp create <newsgroup>
Example: nntp create ampr.news.nrn.sources
*/
static int
donncreate(int argc,char **argv,void *p)
{
FILE *f;
char line[LineLen];
int update_cntrl = 0;
if((f = Fopen(Pointer,READ_TEXT,0,1)) == NULLFILE) {
return -1;
}
for (;;) {
if(fgets(line,LineLen,f) == NULL) {
/* update pointerfile */
update_cntrl = 1;
break;
}
if(strcspn(line," ") != strlen(argv[1])) {
continue;
}
if(strnicmp(argv[1],line,strlen(argv[1])) == 0) {
/* newsgroup in pointerfile exists */
break;
}
}
Fclose(f);
/* creating path to this newsgroup */
if(make_path(argv[1],update_cntrl)) {
return -1;
}
if((f = Fopen(Active,APPEND_TEXT,0,0)) == NULLFILE) {
return -1;
}
for (;;) {
if(fgets(line,LineLen,f) == NULL) {
/* update active file */
fprintf(f,"%s 00000 00001 y\n",argv[1]);
break;
}
if (strcspn(line," ") != strlen(argv[1])) {
continue;
}
if (strnicmp(argv[1],line,strlen(argv[1])) == 0) {
/* newsgroup in active file exists */
break;
}
}
Fclose(f);
return 0;
}
#endif
/* drops nntp servers from list */
static int
donndrops(int argc,char **argv,void *p)
{
dropserver(IPPORT_NNTP,argv[1]);
return 0;
}
#ifdef XXX
/* copies a news from given newsgroup to the mailbox */
static int
donndump(int argc,char **argv,void *p)
{
FILE *t, *f, *o;
char line[LineLen], newsname[10], *cp;
struct ffblk blk;
struct article *art = mxallocw(sizeof(struct article));
art->group = strxdup(argv[1]);
if(get_path2(art) < 1)
goto error2;
rip(art->path);
sprintf(line,"%s/*.*",art->path);
if(findfirst(line,&blk,0)) {
tputs("No news in newsgroup\n");
goto error;
}
sprintf(newsname,"%.8s",argv[2]);
sprintf(line,"%s/%s.txt",Mailspool,newsname);
if((o = Fopen(line,"a+",0,1)) == NULLFILE)
goto error;
if(!(mlock(Mailspool,newsname))) {
tprintf("Newsgroup dump to %s\n",line);
for (;;) {
if((t = Tmpfile(0,1)) == NULLFILE) {
Fclose(o);
goto error;
}
sprintf(line,"%s/%s",art->path,blk.ff_name);
/* Open the article */
if ((f = Fopen(line,READ_TEXT,0,1)) == NULLFILE) {
Fclose(t);
Fclose(o);
goto error;
}
pwait(NULL);
tputs("."); /* One article/dot processed */
tflush();
while(fgets(line,LineLen,f) != NULL) {
fputs(line,t);
if (!strnicmp(line,frm,6)) {
cp = strchr(line,' ') + 1;
fprintf(o,"From %s",cp);
}
}
rewind(t);
while(fgets(line,LineLen,t) != NULL)
fputs(line,o);
fputc('\n',o);
Fclose(t);
Fclose(f);
if (findnext(&blk))
break;
}
rmlock(Mailspool,newsname);
} else
tputs("Mailfile is busy, try later");
Fclose(o);
tputs("\n");
error:
xfree(art->path);
error2:
xfree(art->group);
xfree(art);
return 0;
}
#endif
static int
donnfull(int argc,char **argv,void *p)
{
if(argc < 2) {
if(Post.fullname != NULLCHAR)
tprintf("%s\n",Post.fullname);
} else {
if(Post.fullname != NULLCHAR)
xfree(Post.fullname);
Post.fullname = strxdup(argv[1]);
}
return 0;
}
static int
donnhost(int argc,char **argv,void *p)
{
if(argc < 2) {
if(Post.host != NULLCHAR)
tprintf("%s\n",Post.host);
} else {
if(Post.host != NULLCHAR)
xfree(Post.host);
Post.host = strxdup(argv[1]);
}
return 0;
}
static int
donnihave(int argc,char **argv,void *p)
{
return setintrc(&NnIhave,"NNTP Ihave",argc,argv,0,2);
}
static int
donnkick(int argc,char **argv,void *p)
{
int32 addr = 0;
struct Server *np;
if(argc > 1 && (addr = resolve(argv[1])) == 0) {
tprintf(Badhost,argv[1]);
return 1;
}
for(np = Server; np != NULLSERVER; np = np->next) {
if(np->protocol != IPPORT_NNTP
|| np->busy
|| (addr && np->address != addr)) {
continue;
} else {
newproc("NNTP Client",1280,nntppoll,0,(void *)np,0,0);
}
}
return 0;
}
#ifdef NNTP_LT
static int
donnlifetime (int argc,char **argv,void *p)
{
return setint(&Nntp_lifetime,"NNTP Lifetime",argc,argv);
}
#endif
/* list nntp servers */
static int
donnlists(int argc,char **argv,void *p)
{
char *a = "Newsgroups";
listserver(IPPORT_NNTP,argv[1],a);
return 0;
}
#ifdef LZW
/* sets LzwActive flag */
static int
donnlzw(int argc,char **argv,void *p)
{
return setbool(&LzwActive,"NNTP LZW",argc,argv);
}
#endif
static int
donnmaxcli(int argc,char **argv,void *p)
{
return setshort(&Nntpmaxcli,"NNTP maxcli",argc,argv);
}
static int
donnorgan(int argc,char **argv,void *p)
{
if(argc < 2) {
if(Post.organ != NULLCHAR)
tprintf("%s\n",Post.organ);
} else {
if(Post.organ != NULLCHAR)
xfree(Post.organ);
Post.organ = strxdup(argv[1]);
}
return 0;
}
/* manually entering new news
* returncode: -1 if error; 0 success */
static int
donnpost(int argc,char **argv,void *p)
{
struct session *sp;
struct nntpserv *mp;
char buf[LineLen], *cp;
long id;
#ifdef NNTP_LT
int32 tmptime;
#endif
FILE *f, *idf, *ufp;
if (!Filecheck)
if(check_system())
return -1;
if((sp = newsession("NNTP Post",MORE,SWAP)) == NULLSESSION) {
tputs(Nosess);
return -1;
}
mp = mxallocw(sizeof(struct nntpserv));
mp->buf = mxallocw(LINELEN);
for (;;) {
if ((f = Tmpfile(0,1)) == NULLFILE) {
goto done;
}
if (Post.user == NULLCHAR) {
Post.user = strxdup(input_line("User name? ",sp));
}
fprintf(f,"%s%s\n",Hdrs[PATH],Post.user);
fprintf(f,"%s%s@%s",Hdrs[FROM],Post.user,Hostname);
if (Post.fullname == NULLCHAR) {
Post.fullname = strxdup(input_line("Fullname? ",sp));
}
fprintf(f," (%s)\n",Post.fullname);
fprintf(f,"%s%s\n",Hdrs[NEWSGROUPS],input_line("Newsgroup? ",sp));
fprintf(f,"%s%s\n",Hdrs[SUBJECT],input_line("Subject? ",sp));
id = get_msgid();
fprintf(f,"%s<%ld@%s>\n",Hdrs[MSGID],id,Hostname);
fprintf(f,"%s%s",Hdrs[DATE],rfc822_date(&currtime));
#ifdef NNTP_LT
tmptime = currtime + DAYS * Nntp_lifetime;
fprintf(f,"%s%s",Hdrs[EXPIRE]rfc822_date(&tmptime));
#endif
fprintf(f,"Sender: NNTP@%s\n",Hostname);
if (Post.reply != NULLCHAR) {
fprintf(f,"%s%s\n",Hdrs[REPLYTO],Post.reply);
}
if (Post.organ != NULLCHAR) {
fprintf(f,"%s%s\n",Hdrs[ORGANIZATION],Post.organ);
}
fputc('\n',f);
tputs("Enter message - end with .\n");
for (;;) {
if(recvline(sp->input,buf,LineLen) == -1) {
break;
}
if(strcmp(buf,".u\n") == 0
|| strcmp(buf,".r\n") == 0) {
tputs("Filename? ");
if(recvline(sp->input,buf,LineLen) == -1) {
break;
}
rip(buf);
if(*buf != '\0'
&& (ufp = Fopen(buf,READ_TEXT,0,1)) != NULLFILE) {
while(fgets(buf,LineLen,ufp) != NULL) {
fputs(buf,f);
}
Fclose(ufp);
}
tputs("(continue)\n");
}
if(*buf == '\032'
|| strcmp(buf,".\n") == 0
|| strcmpi(buf,"***END\n") == 0
|| strcmpi(buf,"/EX\n") == 0) {
break;
}
fputs(buf,f);
}
if (Post.sig != NULLCHAR) {
if ((idf = Fopen(Post.sig,READ_TEXT,0,0)) != NULLFILE ) {
while(fgets(buf,LineLen,idf) != NULL) {
fputs(buf,f);
}
Fclose(idf);
tputs("(Sig-file added)\n");
}
}
tputs("\n");
loop: cp = input_line("[Send, Abort, Exit, List] ",sp);
switch(tolower(*cp)) {
case 's':
rewind(f);
sprintf(mp->buf,"<%ld@%s>",id,Hostname);
mp->id = strxdup(mp->buf);
xfer_article2(f,mp);
break;
case 'l':
rewind(f);
while(fgets(buf,LineLen,f) != NULL)
tputs(buf);
rewind(f);
goto loop;
case 'e':
Fclose(f);
goto done;
case 'a':
break;
default:
goto loop;
}
Fclose(f);
cp = input_line("Post another? (y/n) ",sp);
if(*cp == 'n' || *cp == 'N') {
goto done;
}
}
done:
keywait(NULLCHAR,1);
xfree(mp->buf);
xfree(mp);
freesession(sp);
return 0;
}
#ifdef POST_ENBL
static int
dopostok(int argc,char **argv,void *p)
{
return setbool(&postingok,"NNTP Posting",argc,argv);
}
#endif
static int
donnquiet(int argc,char **argv,void *p)
{
return setintrc(&Nntpquiet,"NNTP quiet",argc,argv,0,3);
}
static int
donnread(int argc,char **argv,void *p)
{
FILE *f;
struct session *sp;
char cp[LINELEN], buf[LINELEN];
int number, row, flag = argc;
struct article *art = mxallocw(sizeof(struct article));
art->group = strxdup(argv[1]);
if(get_path2(art) == 1) {
if(argc > 2) {
number = atoi(argv[2]);
} else
number = 1;
sprintf(cp,"%s/news.rc",art->path);
if(flag < 3 && (f = Fopen(cp,READ_TEXT,0,0)) != NULLFILE) {
if(fgets(buf,LINELEN,f) != NULL) {
number = atoi(buf);
number++;
}
Fclose(f);
}
if((sp = newsession("NNTP read",MORE,SWAP)) != NULLSESSION) {
for(;;) {
if(number < 1)
number = 1;
sp->ttystate.echo = sp->ttystate.edit = 0;
row = Nrows - 4;
sprintf(cp,"%s/%d",art->path,number);
if((f = Fopen(cp,READ_TEXT,0,0)) != NULLFILE) {
tprintf("Msg #%d\n",number);
while(fgets(buf,LINELEN,f) != NULL) {
tputs(buf);
if(--row == 0){
row = keywait("--More--",0);
switch(row){
case -1:
case 'q':
Fclose(f);
goto done;
case '\n':
case '\r':
row = 1;
break;
default:
row = Nrows - 3;
}
}
}
Fclose(f);
} else {
number--;
tputs("No more news");
}
done:
row = keywait("\nRead next/previous? (n/p/q)",0);
switch(row) {
case -1:
case 'q':
goto done2;
case 'p':
flag = 3;
if(--number < 1)
goto done2;
continue;
default:
number++;
continue;
}
}
done2:
if(flag < 3) {
sprintf(cp,"%s/news.rc",art->path);
if((f = Fopen(cp,WRITE_TEXT,0,0)) != NULLFILE) {
sprintf(cp,"%d\n",number);
fputs(cp,f);
Fclose(f);
}
}
xfree(art->path);
keywait(NULLCHAR,1);
freesession(sp);
}
} else {
tprintf("No such newsgroup %s\n",art->group);
}
xfree(art->group);
xfree(art);
return 0;
}
static int
donnreply(int argc,char **argv,void *p)
{
if(argc < 2) {
if(Post.reply != NULLCHAR)
tprintf("%s\n",Post.reply);
} else {
if(Post.reply != NULLCHAR)
xfree(Post.reply);
Post.reply = strxdup(argv[1]);
}
return 0;
}
static int
donnsig(int argc,char **argv,void *p)
{
char buf[80];
if(argc < 2) {
if(Post.sig != NULLCHAR)
tprintf("%s\n",Post.sig);
} else if(argc > 1) {
sprintf(buf,"%s/%s",Signature,argv[1]);
if(access(buf,0) == 0) {
if(Post.sig != NULLCHAR)
xfree(Post.sig);
Post.sig = strxdup(buf);
} else {
tputs("No such signature file\n");
return -1;
}
}
return 0;
}
static int
donnuser(int argc,char **argv,void *p)
{
if(argc < 2) {
if(Post.user != NULLCHAR)
tprintf("%s\n",Post.user);
} else {
if(Post.user != NULLCHAR)
xfree(Post.user);
Post.user = strxdup(argv[1]);
}
return 0;
}
/* cmd parser */
int
donntp(int argc,char **argv,void *p)
{
struct cmds Nntp[] = {
{"active", donnactive, 0, 0, NULLCHAR},
{"add", donnadds, 0, 3, "nntp add <server> <newsgroups>"},
#ifdef NNTPENH
{"config", donnconfig, 0, 0, NULLCHAR},
{"create", donncreate, 0, 2, "nntp create <newsgroup>"},
#endif
{"drop", donndrops, 0, 2, "nntp drop <server>"},
#ifdef XXX
{"dump", donndump, 0, 3, "nntp dump <newsgroup> <mailfile>"},
#endif
{"fullname", donnfull, 0, 0, NULLCHAR},
{"hostname", donnhost, 0, 0, NULLCHAR},
{"ihave", donnihave, 0, 0, NULLCHAR},
{"kick", donnkick, 0, 0, NULLCHAR},
#ifdef NNTP_LT
{"lifetime", donnlifetime,0,0, NULLCHAR},
#endif
{"list", donnlists, 0, 0, NULLCHAR},
#ifdef LZW
{"lzw", donnlzw, 0, 0, NULLCHAR},
#endif
{"maxclient", donnmaxcli, 0, 0, NULLCHAR},
{"organ", donnorgan, 0, 0, NULLCHAR},
{"post", donnpost, 2048, 0, NULLCHAR},
#ifdef POST_ENBL
{"postok", dopostok, 0, 0, NULLCHAR},
#endif
{"quiet", donnquiet, 0, 0, NULLCHAR},
{"read", donnread, 1280, 2, "nntp read <newsgroup> [number]"},
{"reply", donnreply, 0, 0, NULLCHAR},
{"signature", donnsig, 0, 0, NULLCHAR},
{"user", donnuser, 0, 0, NULLCHAR},
NULLCHAR,
};
return (subcmd(Nntp,argc,argv,p));
}